package com.jianjun.project.system.role;

import cn.hutool.core.convert.Convert;
import cn.hutool.http.Method;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.jfinal.aop.Inject;
import com.jfinal.core.ActionKey;
import com.jfinal.core.Controller;
import com.jfinal.core.Path;
import com.jfinal.kit.JsonKit;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.Page;
import com.jianjun.common.constant.HttpStatus;
import com.jianjun.common.util.SecurityUtils;
import com.jianjun.framework.security.LoginUser;
import com.jianjun.framework.security.service.SysPermissionService;
import com.jianjun.framework.security.service.TokenService;
import com.jianjun.framework.web.domain.AjaxResult;
import com.jianjun.framework.web.interceptor.DataScope;
import com.jianjun.framework.web.page.TableDataInfo;
import com.jianjun.framework.web.render.ExcelWriterRender;
import com.jianjun.project.common.model.SysDept;
import com.jianjun.project.common.model.SysRole;
import com.jianjun.project.common.model.SysUser;
import com.jianjun.project.common.model.SysUserRole;
import com.jianjun.project.system.dept.SysDeptService;
import com.jianjun.project.system.user.SysUserService;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 角色信息
 *
 * @author source
 */
@Path(value = "/system/role")
public class SysRoleController extends Controller {
    @Inject
    SysRoleService roleService;
    @Inject
    TokenService tokenService;
    @Inject
    SysUserService userService;
    @Inject
    SysPermissionService permissionService;
    @Inject
    SysDeptService deptService;

    @DataScope(deptAlias = "d", permission = "system:role:list")
    public void list() {
        SysRole role = JsonKit.parse(getKv().toJson(), SysRole.class);
        Page<SysRole> page = roleService.paginate(role);
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setMsg("查询成功");
        rspData.setRows(page.getList());
        rspData.setTotal(page.getTotalRow());
        renderJson(rspData);
    }

    @DataScope(deptAlias = "d", permission = "system:role:export")
    public void export() {
        SysRole role = JsonKit.parse(getKv().toJson(), SysRole.class);
        List<SysRole> list = roleService.selectRoleList(role);
        List<Map<String, Object>> mapList = list.stream().map(Model::toMap).collect(Collectors.toList());
        ExcelWriter writer = ExcelUtil.getWriter(true);
        writer.write(mapList, true);
        render(new ExcelWriterRender(writer, role.getClass().getSimpleName()));
    }

    @DataScope(deptAlias = "d", permission = "system:role:query,system:role:add,system:role:edit,system:role:remove")
    public void index() {
        String method = getRequest().getMethod();
        //查询
        if (Method.GET.name().equals(method)) {
            Long roleId = getParaToLong();
            roleService.checkRoleDataScope(roleId);
            renderJson(AjaxResult.success(roleService.selectRoleById(roleId)));
        }
        //新增
        if (Method.POST.name().equals(method)) {
            SysRole role = JsonKit.parse(getRawData(), SysRole.class);
            if (!roleService.checkRoleNameUnique(role)) {
                renderJson(AjaxResult.error("新增角色'" + role.getRoleName() + "'失败，角色名称已存在"));
                return;
            } else if (!roleService.checkRoleKeyUnique(role)) {
                renderJson(AjaxResult.error("新增角色'" + role.getRoleName() + "'失败，角色权限已存在"));
                return;
            }
            role.setCreateBy(SecurityUtils.getUsername());
            renderJson(AjaxResult.success(roleService.insertRole(role)));
        }
        //修改
        if (Method.PUT.name().equals(method)) {
            SysRole role = JsonKit.parse(getRawData(), SysRole.class);
            roleService.checkRoleAllowed(role);
            roleService.checkRoleDataScope(role.getRoleId());
            if (!roleService.checkRoleNameUnique(role)) {
                renderJson(AjaxResult.error("修改角色'" + role.getRoleName() + "'失败，角色名称已存在"));
                return;
            } else if (!roleService.checkRoleKeyUnique(role)) {
                renderJson(AjaxResult.error("修改角色'" + role.getRoleName() + "'失败，角色权限已存在"));
                return;
            }
            role.setUpdateBy(SecurityUtils.getUsername());
            if (roleService.updateRole(role)) {
                // 更新缓存用户权限
                LoginUser loginUser = SecurityUtils.getLoginUser();
                if (Objects.nonNull(loginUser.getUser()) && !loginUser.getUser().isAdmin()) {
                    loginUser.setUser(userService.selectUserByUserName(loginUser.getUser().getUserName()));
                    loginUser.setPermissions(permissionService.getMenuPermission(loginUser.getUser()));
                    tokenService.setLoginUser(loginUser);
                }
                renderJson(AjaxResult.success());
                return;
            }
            renderJson(AjaxResult.error("修改角色'" + role.getRoleName() + "'失败，请联系管理员"));
        }
        //删除
        if (Method.DELETE.name().equals(method)) {
            roleService.deleteRoleByIds(Convert.toLongArray(getPara()));
            renderJson(AjaxResult.success());
        }
    }


    /**
     * 获取角色选择框列表
     */
    @DataScope(deptAlias = "d", permission = "system:role:query")
    public void optionselect() {
        renderJson(AjaxResult.success(roleService.selectRoleList(new SysRole())));
    }


    /**
     * 获取对应角色部门树列表
     */
    @DataScope(deptAlias = "d")
    public void deptTree() {
        Long roleId = getParaToLong();
        AjaxResult ajax = AjaxResult.success();
        ajax.put("checkedKeys", roleService.selectDeptListByRoleId(roleId));
        ajax.put("depts", deptService.selectDeptTreeList(new SysDept()));
        renderJson(ajax);
    }


    /**
     * 修改保存数据权限
     */
    @DataScope(deptAlias = "d", permission = "system:role:edit")
    public void dataScope() {
        SysRole role = JsonKit.parse(getRawData(), SysRole.class);
        roleService.checkRoleAllowed(role);
        roleService.checkRoleDataScope(role.getRoleId());
        renderJson(AjaxResult.ajax(roleService.authDataScope(role)));
    }


    /**
     * 状态修改
     */
    @DataScope(deptAlias = "d", permission = "system:role:edit")
    public void changeStatus() {
        SysRole role = JsonKit.parse(getRawData(), SysRole.class);
        roleService.checkRoleAllowed(role);
        roleService.checkRoleDataScope(role.getRoleId());
        role.setUpdateBy(SecurityUtils.getUsername());
        renderJson(AjaxResult.ajax(roleService.updateRoleDb(role)));
    }


    /**
     * 查询已分配用户角色列表
     */
    @ActionKey("/system/role/authUser/allocatedList")
    @DataScope(permission = "system:role:list")
    public void allocatedList() {
        SysUser user = JsonKit.parse(getKv().toJson(), SysUser.class);
        Page<SysUser> page = userService.selectAllocatedList(user);
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setMsg("查询成功");
        rspData.setRows(page.getList());
        rspData.setTotal(page.getTotalRow());
        renderJson(rspData);
    }

    /**
     * 查询未分配用户角色列表
     */
    @ActionKey("/system/role/authUser/unallocatedList")
    @DataScope(permission = "system:role:list")
    public void unallocatedList() {
        SysUser user = JsonKit.parse(getKv().toJson(), SysUser.class);
        Page<SysUser> page = userService.selectUnallocatedList(user);
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setMsg("查询成功");
        rspData.setRows(page.getList());
        rspData.setTotal(page.getTotalRow());
        renderJson(rspData);
    }

    /**
     * 取消授权用户
     */
    @ActionKey("/system/role/authUser/cancel")
    @DataScope(permission = "system:role:edit")
    public void cancelAuthUser() {
        SysUserRole userRole = JsonKit.parse(getRawData(), SysUserRole.class);
        renderJson(AjaxResult.ajax(roleService.deleteAuthUser(userRole)));
    }

    /**
     * 批量取消授权用户
     */
    @ActionKey("/system/role/authUser/cancelAll")
    @DataScope(permission = "system:role:edit")
    public void cancelAuthUserAll() {
        Long roleId = getParaToLong("roleId");
        Long[] userIds = getParaValuesToLong("userIds");
        renderJson(AjaxResult.ajax(roleService.deleteAuthUsers(roleId, userIds)));
    }

    /**
     * 批量选择用户授权
     */
    @ActionKey("/system/role/authUser/selectAll")
    @DataScope(deptAlias = "d", permission = "system:role:edit")
    public void selectAuthUserAll() {
        Long roleId = getParaToLong("roleId");
        Long[] userIds = getParaValuesToLong("userIds");
        roleService.checkRoleDataScope(roleId);
        renderJson(AjaxResult.ajax(roleService.insertAuthUsers(roleId, userIds)));
    }

}
